package com.ykdl.member.kid.image;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Lock;

import android.text.TextUtils;

public class FileCache {
	private static final String CACHE_TABLE_FILENAME = "cache";
	private static final int MAX_CAPACITY = 1000;
	private String mPath;
	private List<String> mTempCacheList = new ArrayList<String>(100);
	private LinkedList<String> mCacheList = new LinkedList<String>();
	private Thread mSaveThread;
	private boolean mChanged = false;
	private Object mSaveLock = new Object();
	private boolean mActive = true;
	private boolean mInited = false;

	public FileCache(String cachePath) {
		mPath = cachePath;
		mChanged = false;
		mActive = true;
		mInited = false;
		mSaveThread = new Thread(new Runnable() {
			@Override
			public void run() {
				while (mActive) {
					if (!mInited) {
						init();
					}
					try {
						Thread.sleep(10 * 1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					if (!mInited) {
						continue;
					}
					List<String> copy;
					synchronized (FileCache.this) {
						if (!mChanged) {
							continue;
						}
						copy = new ArrayList<String>(mCacheList);
					}
					saveCacheFiles(copy);
				}
			}
		});
		mSaveThread.start();
	}

	private void init() {
		String state = android.os.Environment.getExternalStorageState();
		if (!android.os.Environment.MEDIA_MOUNTED.equals(state)) {
			return;
		}
		if (!android.os.Environment.getExternalStorageDirectory().canWrite()) {
			return;
		}
		try {
			List<String> cacheFiles = getCacheFiles();
			mCacheList.addAll(cacheFiles);
			File path = new File(mPath);
			if (!path.exists()) {
				path.mkdirs();
			}
			File[] files = path.listFiles();
			String fileName;
			for (File file : files) {
				if (!file.isFile()) {
					continue;
				}
				fileName = file.getName();
				if (CACHE_TABLE_FILENAME.equals(fileName)) {
					continue;
				}
				if (!cacheFiles.contains(fileName)) {
					try {
						file.delete();
					} catch (Exception e) {
					}
				}
			}
			synchronized (FileCache.this) {
				if (mTempCacheList.size() > 0) {
					for (String f : mTempCacheList) {
						_putFile(f);
					}
					mTempCacheList.clear();
					mChanged = true;
				}
				mInited = true;
			}
		} catch (Exception e) {
		}
	}

	public synchronized void dispose() {
		mActive = false;
	}

	public synchronized void save() {
		if (!mChanged || !mInited) {
			return;
		}
		saveCacheFiles(mCacheList);
	}

	public synchronized void putFile(String fileName) {
		if (TextUtils.isEmpty(fileName)) {
			return;
		}
		if (mCacheList.size() > 0) {
			String first = mCacheList.getFirst();
			if (fileName.equals(first)) {
				return;
			}
		}
		if (mInited) {
			_putFile(fileName);
		} else {
			mTempCacheList.add(fileName);
		}
	}

	private void _putFile(String fileName) {
		int index = mCacheList.indexOf(fileName);
		if (index > -1) {
			mCacheList.remove(index);
		}
		mCacheList.addFirst(fileName);
		while (mCacheList.size() > MAX_CAPACITY) {
			File file = new File(mPath + mCacheList.getLast());
			try {
				file.delete();
			} catch (Exception e) {
			}
			mCacheList.removeLast();
		}
		mChanged = true;
	}

	private List<String> getCacheFiles() {
		File cacheTableFile = new File(mPath + CACHE_TABLE_FILENAME);
		if (cacheTableFile.exists()) {
			try {
				InputStreamReader inputReader = new InputStreamReader(
						new FileInputStream(cacheTableFile));
				BufferedReader bufReader = new BufferedReader(inputReader);
				LineNumberReader reader = new LineNumberReader(bufReader);
				String s = reader.readLine();
				List<String> files = new ArrayList<String>(MAX_CAPACITY);
				while (s != null) {
					if (s.length() > 0) {
						files.add(s);
					}
					s = reader.readLine();
				}
				reader.close();
				bufReader.close();
				return files;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return new ArrayList<String>(0);
	}

	private void saveCacheFiles(List<String> files) {
		synchronized (mSaveLock) {
			try {
				File cacheTableFile = new File(mPath + CACHE_TABLE_FILENAME);
				if (cacheTableFile.exists()) {
					cacheTableFile.delete();
				}
				cacheTableFile.createNewFile();
				PrintStream writer = null;
				try {
					cacheTableFile.delete();
					cacheTableFile.createNewFile();
					writer = new PrintStream(cacheTableFile);
					for (String file : files) {
						writer.println(file);
					}
					writer.flush();
					writer.close();
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					if (writer != null) {
						writer.close();
					}
				}
				mChanged = false;
			} catch (Exception e) {
			}
		}
	}
}
